<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_FormParam
{
    public $arrValue = array();
    public $disp_name = array();
    public $keyname = array();
    public $arrDefault = array();
    public $input_db = array();

    /**
     * コンストラクタ
     */
    public function __construct(){}

    /**
     * 前方互換用
     *
     * @deprecated 2.12.0 #1702
     */
    public function initParam()
    {
        $this->disp_name  = array();
        $this->keyname    = array();
        $this->arrDefault = array();
        $this->input_db   = array();
    }

    // パラメーターの追加
    public function addParam($disp_name, $keyname, $default = '', $input_db = true)
    {
        $index = array_search($keyname, $this->keyname);
        if($index !== FALSE){
            // overwrite
            $this->disp_name[$index] = $disp_name;
            $this->keyname[$index]   = $keyname;
            $this->arrDefault[$index]= $default;
            $this->input_db[$index]  = $input_db;
        } else {
            $this->disp_name[] = $disp_name;
            $this->keyname[]   = $keyname;
            $this->arrDefault[$keyname] = $default;
            $this->input_db[]  = $input_db;
        }
    }

    // パラメーターの入力
    // $arrVal  :$arrVal['keyname']・・の配列を一致したキーのインスタンスに格納する
    // $seq     :trueの場合、$arrVal[0]~の配列を登録順にインスタンスに格納する
    public function setParam($arrVal, $seq = false)
    {
        if (!is_array($arrVal)) return;
        if (!$seq) {
            foreach ($arrVal as $key => $val) {
                $this->setValue($key, $val);
            }
        } else {
            foreach ($this->keyname as $index => $key) {
                $this->setValue($key, $arrVal[$index]);
            }
        }
    }

    // 複数列パラメーターの取得
    public function setParamList($arrVal2d, $keyname)
    {
        // DBの件数を取得する。
        $no = 1;
        foreach ($arrVal2d as $arrVal) {
            $key = $keyname . $no;
            $this->setValue($key, $arrVal[$keyname]);
            $no++;
        }
    }

    // キーに対応した値をセットする。
    public function setValue($key, $value)
    {
        if (!in_array($key, $this->keyname)) {
            // TODO 警告発生
            return;
        }
        $this->arrValue[$key] = $value;
    }

    public function toLower($key)
    {
        if (isset($this->arrValue[$key])) {
            $this->arrValue[$key] = strtolower($this->arrValue[$key]);
        }
    }

    /**
     * 連想配列で返す
     *
     * @param  array $arrKey 対象のキー
     * @return array 連想配列
     */
    public function getHashArray($arrKey = array())
    {
        $arrRet = array();
        foreach ($this->keyname as $keyname) {
            if (empty($arrKey) || in_array($keyname, $arrKey)) {
                $arrRet[$keyname] = $this->getValue($keyname);
            }
        }

        return $arrRet;
    }

    // DB格納用配列の作成
    public function getDbArray()
    {
        $dbArray = array();
        foreach ($this->keyname as $index => $key) {
            if ($this->input_db[$index]) {
                $dbArray[$key] = $this->getValue($key);
            }
        }

        return $dbArray;
    }

    /**
     * 配列の縦横を入れ替えて返す
     *
     * @param  array $arrKey 対象のキー
     * @return array 縦横を入れ替えた配列
     */
    public function getSwapArray($arrKey = array())
    {
        $arrTmp = $this->getHashArray($arrKey);

        return SC_Utils_Ex::sfSwapArray($arrTmp);
    }

    // 項目名一覧の取得
    public function getTitleArray()
    {
        return $this->disp_name;
    }

    // 項目数を返す
    public function getCount()
    {
        $count = count($this->keyname);

        return $count;
    }

    // フォームに渡す用のパラメーターを返す
    public function getFormParamList()
    {
        $formParamList = array();
        foreach ($this->keyname as $index => $key) {
            // キー名
            $formParamList[$key]['keyname'] = $key;
            // 表示名
            $formParamList[$key]['disp_name'] = $this->disp_name[$index];
            // 入力値
            $formParamList[$key]['value'] = $this->getValue($key);
        }

        return $formParamList;
    }

    /**
     * キー名の一覧を返す
     *
     * @return array キー名の一覧
     */
    public function getKeyList()
    {
        return $this->keyname;
    }

    // キー名と一致した値を返す
    public function getValue($keyname, $default = '')
    {
        $ret = null;
        foreach ($this->keyname as $key) {
            if ($key == $keyname) {
                $ret = isset($this->arrValue[$key]) ? $this->arrValue[$key] : $this->arrDefault[$key];
                break;
            }
        }

        if (is_array($ret)) {
            foreach ($ret as $key => $value) {
                if (empty($ret[$key])) {
                    $ret[$key] = $default;
                }
            }
        } else {
            if (is_null($ret)) {
                $ret = $default;
            }
        }

        return $ret;
    }

    /**
     * @deprecated
     */
    public function splitParamCheckBoxes($keyname)
    {
        foreach ($this->keyname as $key) {
            if ($key == $keyname) {
                if (isset($this->arrValue[$key]) && !is_array($this->arrValue[$key])) {
                    $this->arrValue[$key] = explode('-', $this->arrValue[$key]);
                }
            }
        }
    }

    /**
     * 入力パラメーターの先頭及び末尾にある空白文字を削除する.
     *
     * @param  boolean $has_wide_space 全角空白も削除する場合 true
     * @return void
     */
    public function trimParam($has_wide_space = true)
    {
        foreach ($this->arrValue as &$value) {
            $this->recursionTrim($value, $has_wide_space);
        }
    }

    /**
     * 再帰的に入力パラメーターの先頭及び末尾にある空白文字を削除する.
     *
     * @param  mixed   $value          変換する値. 配列の場合は再帰的に実行する.
     * @param  boolean $has_wide_space 全角空白も削除する場合 true
     * @return void
     */
    public function recursionTrim(&$value, $has_wide_space = true)
    {
        $pattern = '/^[ 　\r\n\t]*(.*?)[ 　\r\n\t]*$/u';
        if (is_array($value)) {
            foreach ($value as $key => $val) {
                $this->recursionTrim($value[$key], $has_wide_space);
            }
        } else {
            if (!empty($value)) {
                if ($has_wide_space) {
                    $value = preg_replace($pattern, '$1', $value);
                }
                $value = trim($value);
            }
        }
    }

    /**
     * 検索結果引き継ぎ用の連想配列を取得する.
     *
     * 引数で指定した文字列で始まるパラメーター名の入力値を連想配列で取得する.
     *
     * @param  string $prefix パラメーター名の接頭辞
     * @return array  検索結果引き継ぎ用の連想配列.
     */
    public function getSearchArray($prefix = 'search_')
    {
        $arrResults = array();
        foreach ($this->keyname as $key) {
            if (preg_match('/^' . $prefix . '/', $key)) {
                $arrResults[$key] = $this->getValue($key);
            }
        }

        return $arrResults;
    }

    /**
     * 前方互換用
     *
     * 1次キーが添字なのが特徴だったと思われる。
     * @deprecated 2.12.0 必要ならば getFormParamList メソッドに引数を追加するなどで実現可能
     */
    public function getFormDispArray()
    {
        $formDispArray = array();
        foreach ($this->keyname as $index => $key) {
            // キー名
            $formDispArray[$index]['keyname'] = $key;
            // 表示名
            $formDispArray[$index]['disp_name']  = $this->disp_name[$index];
            // 文字数制限
            $formDispArray[$index]['length'] = $this->length[$index];
            // 入力値
            $formDispArray[$index]['value'] = $this->getValue($key);
        }

        return $formDispArray;
    }

    /**
     * パラメーターの削除
     *
     * addParamの逆の関数
     */
    public function removeParam($keyname)
    {
        $index = array_search($keyname, $this->keyname);

        if ($index !== FALSE) {
            // 削除
            unset($this->disp_name[$index]);
            unset($this->keyname[$index]);
            unset($this->arrDefault[$keyname]);
            unset($this->input_db[$index]);

            // 歯抜けになった配列を詰める
            $this->disp_name    = array_merge($this->disp_name);
            $this->keyname      = array_merge($this->keyname);
            $this->input_db     = array_merge($this->input_db);
        }
    }

    /**
     * パラメーター定義の上書き
     *
     * @param string $keyname キー名
     * @param string $target  上書きしたい項目名(disp_name等)
     * @param mixed  $value   指定した内容に上書きする
     */
    public function overwriteParam($keyname, $target, $value)
    {
        $index = array_search($keyname, $this->keyname);

        if ($index !== FALSE) {
            $this->{$target}[$index] = $value;
        }
    }
}
